package com.intretech.umsin.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.intretech.umsin.security.satoken.model.AppletLoginUser;
import com.intretech.umsin.security.satoken.model.LoginUser;
import com.intretech.umsin.security.satoken.model.Role;
import com.intretech.umsin.system.converter.SysUserVoEntityConverter;
import com.intretech.umsin.system.entity.SysUserEntity;
import com.intretech.umsin.system.enums.UserStatus;
import com.intretech.umsin.system.exception.SystemCenterException;
import com.intretech.umsin.system.mapper.SysUserMapper;
import com.intretech.umsin.system.param.SysUserParam;
import com.intretech.umsin.system.service.SysMenuService;
import com.intretech.umsin.system.service.SysRoleService;
import com.intretech.umsin.system.service.SysUserService;
import com.intretech.umsin.system.vo.SysUserVo;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;



/**
* @version V1.0
* 用户信息:sys_user 对应商业服务实现.
* @ClassName: SysUserServiceImpl
* @Description: 用户信息:sys_user 对应商业服务实现.
* @author: 李启联
* @date:   2022-8-6 14:37:22
* @Copyright: Copyright (c) 2022
*/
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUserEntity> implements SysUserService {

    @Autowired
    private SysUserVoEntityConverter sysUserVoEntityConverter;

    @Autowired
    SysRoleService sysRoleService;
    @Autowired
    SysMenuService sysMenuService;


    /**
    * 根据ID查询单个用户信息对象
    * @param id 组键ID
    * @return 单个用户信息VO对象
    */
    public SysUserVo queryById(Serializable id){
        if (id == null) {return null;}
        return sysUserVoEntityConverter.reverseFromTarget(this.getById(id));
    }


    /**
    * 根据ID集合查询返回用户信息列表
    * @param idList 组键ID集合
    * @return 用户信息列表
    */
    public List<SysUserVo> queryByIds(Collection<? extends Serializable> idList){
        if(CollectionUtils.isEmpty(idList)){return null;}
        return sysUserVoEntityConverter.reverseFromTarget(this.listByIds(idList));
    }


    /**
    * 分页查询 用户信息 信息
    * @param page 分页对象
    * @param param 查询参数
    * @return IPage<SysUserVo> 分页对象
    */
    @Override
    public IPage<SysUserVo> queryForPage(IPage page,SysUserParam param){
      IPage<SysUserEntity> page0 = this.page(page,createQueryWrapper(param));
      IPage<SysUserVo> pageResult = page0.convert(e -> sysUserVoEntityConverter.reverseFromTarget(e));
      return pageResult;
    }


    /**
    * 根据条件查询返回 用户信息 对象列表
    * @param  param 查询参数
    * @return 用户信息 对象列表
    */
    @Override
    public List<SysUserVo> queryForList(SysUserParam param) {
        List<SysUserEntity> list = this.list(createQueryWrapper(param));
        return sysUserVoEntityConverter.reverseFromTarget(list);
    }

    /**
    * 构建查询条件
    * @param param 查询参数实体对象
    * @return 构建后的QueryWrapper查询条件
    */
    private QueryWrapper<SysUserEntity> createQueryWrapper(SysUserParam param){
        QueryWrapper<SysUserEntity> queryWrapper = new QueryWrapper<>();
        if(ObjectUtils.isEmpty(param)) { return queryWrapper; }
        Optional<SysUserParam> op = Optional.of(param);
        queryWrapper.lambda()
                .eq(op.map(SysUserParam::getId).isPresent(),SysUserEntity::getId,param.getId())
                .eq(op.map(SysUserParam::getDeptId).isPresent(),SysUserEntity::getDeptId,param.getDeptId())
                .eq(op.map(SysUserParam::getUsername).filter(StringUtils::isNotBlank).isPresent(),SysUserEntity::getUsername,param.getUsername())
                .eq(op.map(SysUserParam::getAccount).filter(StringUtils::isNotBlank).isPresent(),SysUserEntity::getAccount,param.getAccount())
                .eq(op.map(SysUserParam::getNickName).filter(StringUtils::isNotBlank).isPresent(),SysUserEntity::getNickName,param.getNickName())
                .eq(op.map(SysUserParam::getSex).filter(StringUtils::isNotBlank).isPresent(),SysUserEntity::getSex,param.getSex())
                .eq(op.map(SysUserParam::getPhone).filter(StringUtils::isNotBlank).isPresent(),SysUserEntity::getPhone,param.getPhone())
                .eq(op.map(SysUserParam::getTel).filter(StringUtils::isNotBlank).isPresent(),SysUserEntity::getTel,param.getTel())
                .eq(op.map(SysUserParam::getEmail).filter(StringUtils::isNotBlank).isPresent(),SysUserEntity::getEmail,param.getEmail())
                .eq(op.map(SysUserParam::getHeadImgUrl).filter(StringUtils::isNotBlank).isPresent(),SysUserEntity::getHeadImgUrl,param.getHeadImgUrl())
                .eq(op.map(SysUserParam::getPassword).filter(StringUtils::isNotBlank).isPresent(),SysUserEntity::getPassword,param.getPassword())
                .eq(op.map(SysUserParam::getAdmin).isPresent(),SysUserEntity::getAdmin,param.getAdmin())
                .eq(op.map(SysUserParam::getEnabled).isPresent(),SysUserEntity::getEnabled,param.getEnabled())
                .eq(op.map(SysUserParam::getBirthday).isPresent(),SysUserEntity::getBirthday,param.getBirthday())
        ;
        return queryWrapper;
    }

    /**
    * 添加用户信息到数据库
    * @param vo  用户信息 VO对象
    * @return 添加后的用户信息 VO对象
    */
    @Override
    public SysUserVo add(SysUserVo vo) {
        if (ObjectUtils.isEmpty(vo)) {return null;}
        SysUserEntity entity = sysUserVoEntityConverter.convertToTarget(vo);
        if(this.save(entity)){
            return sysUserVoEntityConverter.reverseFromTarget(this.getById(entity.getId()));
        }else {
            throw new RuntimeException("添加 用户信息 单个对象失败!");
            //return null;
        }
    }

    /**
    * 添加用户信息集合列表到数据库
    * @param vos  用户信息 VO对象列表
    * @return 添加后的用户信息 VO对象集合列表
    */
    @Override
    public List<SysUserVo> adds(List<SysUserVo> vos) {
        if (CollectionUtils.isEmpty(vos)) { return null; }
        List<SysUserEntity> entities = sysUserVoEntityConverter.convertToTarget(vos);
        if(this.saveBatch(entities)){
            List<Serializable> ids = new ArrayList<>();
            entities.forEach(e->{ids.add(e.getId());});
            return sysUserVoEntityConverter.reverseFromTarget(this.listByIds(ids));
        }else {
           throw new RuntimeException("添加 用户信息 集合列表失败!");
           //return null;
        }
    }

    /**
    * 更新用户信息到数据库
    * @param vo 要更新的用户信息 VO对象
    * @return 更新后的用户信息 VO对象
    */
    @Override
    public SysUserVo modify(SysUserVo vo) {
        if (ObjectUtils.isEmpty(vo)) {return null;}
        SysUserEntity entity = sysUserVoEntityConverter.convertToTarget(vo);
        if(this.updateById(entity)){
            return sysUserVoEntityConverter.reverseFromTarget(this.getById(entity.getId()));
        }else {
            throw new RuntimeException("更新用户信息单个对象失败!");
            //return null;
        }
    }

    /**
    * 更新用户信息集合列表到数据库
    * @param vos 要更新的用户信息 VO对象集合
    * @return 更新后的用户信息 VO对象集合
    */
    @Override
    public List<SysUserVo> modifys(List<SysUserVo> vos) {
        if (CollectionUtils.isEmpty(vos)) { return null; }
        List<SysUserEntity> entities = sysUserVoEntityConverter.convertToTarget(vos);
        if(this.updateBatchById(entities)){
            List<Serializable> ids = new ArrayList<>();
            entities.forEach(e->{ids.add(e.getId());});
            return sysUserVoEntityConverter.reverseFromTarget(this.listByIds(ids));
        }else {
            throw new RuntimeException("更新用户信息集合列表失败!");
            //return null;
        }
    }

    /**
     * 通过用户名查询用户信息
     *
     * @param account 用户名
     * @return 结果
     */
    @Override
    public LoginUser getUserInfo(String account) {
        SysUserEntity user = this.getBaseMapper().getUserByAccount(account);
        if(ObjectUtils.isEmpty(user)){
            throw new SystemCenterException("user not exists","user.not.exists",account);
        }
        if(UserStatus.DISABLED.equals(user.getEnabled())){
            throw new SystemCenterException("user disabled","user.disabled",account);
        }

        // 此处可根据登录用户的数据不同 自行创建 loginUser
        return buildLoginUser(user);
    }

    /**
     * 通过手机号查询用户信息
     *
     * @param phonenumber 手机号
     * @return 结果
     */
    @Override
    public LoginUser getUserInfoByPhonenumber(String phonenumber) {
        SysUserEntity user = this.getBaseMapper().getUserByPhone(phonenumber);
        if(ObjectUtils.isEmpty(user)){
            throw new SystemCenterException("user not exists","user.not.exists",phonenumber);
        }
        if(UserStatus.DISABLED.equals(user.getEnabled())){
            throw new SystemCenterException("user disabled","user.disabled",phonenumber);
        }
        // 此处可根据登录用户的数据不同 自行创建 loginUser
        return buildLoginUser(user);
    }

    /**
     * 通过openid查询用户信息
     *
     * @param openid openid
     * @return 结果
     */
    @Override
    public AppletLoginUser getUserInfoByOpenid(String openid) {
        // todo 自行实现 userService.selectUserByOpenid(openid);
        SysUserEntity sysUser = new SysUserEntity();
        if (ObjectUtil.isNull(sysUser)) {
            // todo 用户不存在 业务逻辑自行实现
        }
        if (UserStatus.DISABLED.getCode().equals(sysUser.getEnabled())) {
            // todo 用户已被停用 业务逻辑自行实现
        }
        // 此处可根据登录用户的数据不同 自行创建 loginUser
        AppletLoginUser loginUser = new AppletLoginUser();
        loginUser.setUserId(sysUser.getId());
        loginUser.setUsername(sysUser.getUsername());
        loginUser.setUserType(sysUser.getUserType());
        loginUser.setOpenid(openid);
        return loginUser;
    }

    /**
     * 注册用户信息
     *
     * @param sysUserVo 用户信息
     * @return 结果
     */
    @Override
    public SysUserVo registerUserInfo(SysUserVo sysUserVo) {
        return null;
    }

    /**
     * 构建登录用户
     */
    private LoginUser buildLoginUser(SysUserEntity user) {
        LoginUser loginUser = new LoginUser();
        loginUser.setUserId(user.getId());
        loginUser.setDeptId(user.getDeptId());
        loginUser.setUsername(user.getUsername());
        loginUser.setPassword(user.getPassword());
        loginUser.setUserType(user.getUserType());
        loginUser.setAccount(user.getAccount());
        loginUser.setMenuPermission(sysMenuService.selectMenuPermsByUserId(user.getId()));
        loginUser.setRolePermission(sysRoleService.selectRolePermissionByUserId(user.getId()));
        loginUser.setDeptName(user.getDeptName());
        List<Role> roles = BeanUtil.copyToList(sysRoleService.selectRolesByUserId(user.getId()), Role.class);
        loginUser.setRoles(roles);
        return loginUser;
    }

}

